﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CreateEditProjectForm.cs" company="Elilink">
//   Defor
// </copyright>
// <summary>
//   Form for editing or creating projects
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Deployment
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;

    using BusinessLayer.Objects;
    using BusinessLayer.Results;

    using DataAccessLayer.Repositories.Abstract;

    using Deployment.Tools;

    /// <summary>
    ///     Form for editing or creating projects
    /// </summary>
    public partial class CreateEditProjectForm : Form
    {
        #region Fields

        /// <summary>
        ///     The _current project
        /// </summary>
        private readonly DeployableProject _currentProject;

        /// <summary>
        ///     The _deployable project repository
        /// </summary>
        private readonly IDeployableProjectRepository _deployableProjectRepository;

        /// <summary>
        ///     The _is edit action
        /// </summary>
        private readonly bool _isEditAction;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        ///     Initializes a new instance of the <see cref="CreateEditProjectForm" /> class.
        /// </summary>
        public CreateEditProjectForm()
        {
            InitializeComponent();
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="CreateEditProjectForm" /> class.
        /// </summary>
        /// <param name="deployableProjectRepository">
        ///     The deployable project repository.
        /// </param>
        /// <param name="targetSystemRepository">
        ///     The target system repository.
        /// </param>
        /// <param name="currentTargetName">
        ///     Name of the current target.
        /// </param>
        public CreateEditProjectForm(
            IDeployableProjectRepository deployableProjectRepository, 
            ITargetSystemRepository targetSystemRepository, 
            string currentTargetName)
            : this()
        {
            _deployableProjectRepository = deployableProjectRepository;
            List<TargetSystem> targets = targetSystemRepository.GetTargetSystems();
            cbxTargets.DataSource = targets.Select(t => t.TargetSystemName).OrderBy(t => t).ToList();
            cbxTargets.SelectedIndex = cbxTargets.Items.IndexOf(currentTargetName);
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="CreateEditProjectForm" /> class.
        /// </summary>
        /// <param name="deployableProjectRepository">
        ///     The deployable project repository.
        /// </param>
        /// <param name="targetSystemRepository">
        ///     The target system repository.
        /// </param>
        /// <param name="deployableProject">
        ///     The deployable project.
        /// </param>
        /// <param name="currentTargetName">
        ///     Name of the current target.
        /// </param>
        public CreateEditProjectForm(
            IDeployableProjectRepository deployableProjectRepository, 
            ITargetSystemRepository targetSystemRepository, 
            DeployableProject deployableProject, 
            string currentTargetName)
            : this(deployableProjectRepository, targetSystemRepository, currentTargetName)
        {
            _currentProject = deployableProject;
            _isEditAction = true;
            txtProjectName.Text = _currentProject.ProjectName;
            txtPublishProfile.Text = _currentProject.PublishProfile;
            txtProjectPath.Text = _currentProject.ProjectPath;
            txtUsername.Text = _currentProject.UserName;
            txtPassword.Text = _currentProject.Password;
        }

        #endregion

        #region Methods

        /// <summary>
        ///     Shows the create dialog.
        /// </summary>
        /// <param name="owner">
        ///     The owner.
        /// </param>
        /// <returns>
        ///     The <see cref="OperationResult" />.
        /// </returns>
        internal OperationResult ShowCreateDialog(Form owner)
        {
            CenterToParent(owner);
            Text = "Create new project";
            switch (ShowDialog(owner))
            {
                case DialogResult.OK:
                    {
                        return new OperationResult(cbxTargets.SelectedValue);
                    }

                default:
                    {
                        return new OperationResult();
                    }
            }
        }

        /// <summary>
        ///     Shows the edit dialog.
        /// </summary>
        /// <param name="owner">
        ///     The owner.
        /// </param>
        /// <returns>
        ///     The <see cref="OperationResult" />.
        /// </returns>
        internal OperationResult ShowEditDialog(Form owner)
        {
            CenterToParent(owner);
            Text = "Edit project";
            switch (ShowDialog(owner))
            {
                case DialogResult.OK:
                    {
                        return new OperationResult(cbxTargets.SelectedValue);
                    }

                default:
                    {
                        return new OperationResult();
                    }
            }
        }

        /// <summary>
        ///     Handles the Click event of the BtnBrowse control.
        /// </summary>
        /// <param name="sender">
        ///     The source of the event.
        /// </param>
        /// <param name="e">
        ///     The <see cref="EventArgs" /> instance containing the event data.
        /// </param>
        private void BtnBrowse_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtProjectPath.Text))
            {
                string path = txtProjectPath.Text.Substring(0, txtProjectPath.Text.LastIndexOf('\\') + 1);
                string fileName = txtProjectPath.Text.Replace(path, string.Empty);
                dlgOpenFile.InitialDirectory = path;
                dlgOpenFile.FileName = fileName;
            }

            if (dlgOpenFile.ShowDialog(this) == DialogResult.OK)
            {
                txtProjectPath.Text = dlgOpenFile.FileName;
            }
        }

        /// <summary>
        ///     Handles the Click event of the BtnCancel control.
        /// </summary>
        /// <param name="sender">
        ///     The source of the event.
        /// </param>
        /// <param name="e">
        ///     The <see cref="EventArgs" /> instance containing the event data.
        /// </param>
        private void BtnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        /// <summary>
        ///     Handles the Click event of the BtnCopy control.
        /// </summary>
        /// <param name="sender">
        ///     The source of the event.
        /// </param>
        /// <param name="e">
        ///     The <see cref="EventArgs" /> instance containing the event data.
        /// </param>
        private void BtnCopy_Click(object sender, EventArgs e)
        {
            SavingButtonClick(true);
        }

        /// <summary>
        ///     Handles the Click event of the BtnSave control.
        /// </summary>
        /// <param name="sender">
        ///     The source of the event.
        /// </param>
        /// <param name="e">
        ///     The <see cref="EventArgs" /> instance containing the event data.
        /// </param>
        private void BtnSave_Click(object sender, EventArgs e)
        {
            SavingButtonClick(false);
        }

        /// <summary>
        ///     Centers to parent.
        /// </summary>
        /// <param name="owner">
        ///     The owner.
        /// </param>
        private void CenterToParent(Form owner)
        {
            Owner = owner;
            CenterToParent();
        }

        /// <summary>
        ///     Checks the input emptiness.
        /// </summary>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        private bool CheckInputEmptiness()
        {
            if (string.IsNullOrEmpty(txtProjectName.Text))
            {
                MessageBoxEx.Show(
                    this, 
                    "Project name should be specified", 
                    "Fill all data", 
                    MessageBoxButtons.OK, 
                    MessageBoxIcon.Error);
                return false;
            }

            /*if (string.IsNullOrEmpty(txtProjectPath.Text))
            {
                MessageBoxEx.Show(this, "Path for project should be specified", "Fill all data",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            if (string.IsNullOrEmpty(txtPublishProfile.Text))
            {
                MessageBoxEx.Show(this, "Publish profile should be specified", "Fill all data",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }*/
            return true;
        }

        /// <summary>
        ///     Performs the action.
        /// </summary>
        /// <param name="isEdit">
        ///     if set to <c>true</c> [is edit].
        /// </param>
        /// <param name="isCopy">
        ///     if set to <c>true</c> [is copy].
        /// </param>
        /// <returns>
        ///     <c>true</c> if XXXX, <c>false</c> otherwise
        /// </returns>
        private bool PerformAction(bool isEdit, bool isCopy)
        {
            var project = new DeployableProject
                              {
                                  ProjectName = txtProjectName.Text, 
                                  ProjectPath = txtProjectPath.Text, 
                                  PublishProfile = txtPublishProfile.Text, 
                                  UserName = txtUsername.Text, 
                                  Password = txtPassword.Text, 
                                  TargetSystemName = cbxTargets.SelectedValue.ToString()
                              };
            OperationResult result = !isEdit
                                         ? _deployableProjectRepository.AddDeployableProject(project)
                                         : isCopy
                                               ? _deployableProjectRepository.AddDeployableProject(project)
                                               : string.Equals(
                                                   _currentProject.TargetSystemName, 
                                                   project.TargetSystemName, 
                                                   StringComparison.CurrentCultureIgnoreCase)
                                                 && string.Equals(
                                                     _currentProject.ProjectName, 
                                                     project.ProjectName, 
                                                     StringComparison.CurrentCultureIgnoreCase)
                                                     ? _deployableProjectRepository.UpdateDeployableProject(project)
                                                     : _deployableProjectRepository.UpdateDeployableProjectFull(
                                                         project, 
                                                         _currentProject.ProjectName, 
                                                         _currentProject.TargetSystemName);

            if (result.ErrorType != 0)
            {
                MessageBoxEx.Show(
                    this, 
                    result.ErrorDescription, 
                    result.ErrorType.ToString(), 
                    MessageBoxButtons.OK, 
                    MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        /// <summary>
        ///     Savings the button click.
        /// </summary>
        /// <param name="isCopy">
        ///     if set to <c>true</c> [is copy].
        /// </param>
        private void SavingButtonClick(bool isCopy)
        {
            if (!CheckInputEmptiness())
            {
                return;
            }

            if (!PerformAction(_isEditAction, isCopy))
            {
                return;
            }

            DialogResult = DialogResult.OK;
            Close();
        }

        #endregion
    }
}